<style scoped>
.label span {
    display: block;
}

.label span:last-child {
    /* margin-left: 10px; */
    font-size: 10px;
    color: #999;
}
</style>
<template>
    <a-drawer :title="title" :maskClosable="false" :width="1000" :visible="modelValue"
        :body-style="{ paddingBottom: '80px' }" @close="onClose">
        <a-form ref="formRef" :model="props.formdata" :rules="rules" layout="vertical">
            <a-divider orientation="left">客户端信息</a-divider>
            <a-card>
                <a-row :gutter="16">
                    <a-col :span="8">
                        <a-form-item name="clientId">
                            <template #label>
                                <div class="label">
                                    <span>客户端ID</span>
                                    <span>此应用程序的唯一识别</span>
                                </div>
                            </template>
                            <a-input v-model:value.trim="props.formdata.clientId" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item name="clientName">
                            <template #label>
                                <div class="label">
                                    <span>显示名称</span>
                                    <span>在同意画面出现的应用程序名称</span>
                                </div>
                            </template>
                            <a-input v-model:value.trim="props.formdata.clientName" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item name="description">
                            <template #label>
                                <div class="label">
                                    <span>说明</span>
                                    <span>备注</span>
                                </div>
                            </template>
                            <a-input v-model:value.trim="props.formdata.description" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="协议类型" name="protocolType">
                            <a-select v-model:value="props.formdata.protocolType" show-search allow-clear
                                :options="ProtocolTypes">
                            </a-select>
                        </a-form-item>
                    </a-col>


                    <a-col :span="8">
                        <a-form-item label="启动开关" name="enabled">
                            <a-switch v-model:checked="props.formdata.enabled" checked-children="开"
                                un-checked-children="关" />
                        </a-form-item>
                    </a-col>
                </a-row>
            </a-card>

            <a-divider orientation="left">客户端密钥</a-divider>
            <a-card>
                <a-form-item name="requireClientSecret">
                    <a-button @click="() => {
                        props.formdata.clientSecrets?.push({})
                    }">
                        <template #icon>
                            <plus-outlined />
                        </template>
                    </a-button>
                    <span style="margin-left:20px;"></span>
                    <a-checkbox v-model:checked="props.formdata.requireClientSecret">需要客户端密钥</a-checkbox>
                </a-form-item>
                <template v-for="(item, index) in props.formdata.clientSecrets">
                    <a-card style="margin-bottom:10px;">
                        <a-row :gutter="16">
                            <a-col :span="24">
                                <span>客户端密钥 {{ index + 1 }}</span>
                                <a-button style="float:right;"
                                    @click="() => { props.formdata.clientSecrets!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="密码" :name="['clientSecrets', index, 'value']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-input v-model:value.trim="item.value" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="说明" :name="['clientSecrets', index, 'description']">
                                    <a-input v-model:value.trim="item.description" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="过期时间" :name="['clientSecrets', index, 'expiration']">
                                    <!-- <a-date-picker v-model:value="item.expiration" format="YYYY-MM-DD" /> -->
                                    <a-input v-model:value.trim="item.expiration" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="12">
                                <a-form-item label="秘钥类型" :name="['clientSecrets', index, 'type']">
                                    <a-select style="width: 360px;" v-model:value="item.type" show-search allow-clear
                                        :options="SecretTypes">
                                    </a-select>
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </a-card>
                </template>
            </a-card>

            <a-row :gutter="16">
                <a-col :span="12">
                    <a-divider orientation="left">资源</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="() => {
                                props.formdata.allowedScopes?.push({})
                            }">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.allowedScopes">
                            <a-input-group compact>
                                <a-form-item :name="['allowedScopes', index, 'scope']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-select style="width: 360px;" v-model:value="item.scope" show-search allow-clear
                                        :options="apiScopeStore.scopes">
                                    </a-select>
                                </a-form-item>
                                <a-button @click="() => { props.formdata.allowedScopes!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
                <a-col :span="12">
                    <a-divider orientation="left">授权模式</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="() => {
                                props.formdata.allowedGrantTypes?.push({})
                            }">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.allowedGrantTypes">
                            <a-input-group compact>
                                <a-form-item :name="['allowedGrantTypes', index, 'grantType']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-select style="width: 360px;" v-model:value="item.grantType" show-search allow-clear
                                        :options="GrantTypes">
                                    </a-select>
                                </a-form-item>
                                <a-button @click="() => { props.formdata.allowedGrantTypes!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
            </a-row>

            <a-row :gutter="16">
                <a-col :span="12">
                    <a-divider orientation="left">客户端登录回调 URL</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="() => {
                                props.formdata.redirectUris?.push({})
                            }">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.redirectUris">
                            <a-input-group compact>
                                <a-form-item :name="['redirectUris', index, 'redirectUri']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-input style="width:360px;" v-model:value.trim="item.redirectUri" />
                                </a-form-item>
                                <a-button @click="() => { props.formdata.redirectUris!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
                <a-col :span="12">
                    <a-divider orientation="left">客户端登出回调 URL</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="() => {
                                props.formdata.postLogoutRedirectUris?.push({})
                            }">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.postLogoutRedirectUris">
                            <a-input-group compact>
                                <a-form-item :name="['postLogoutRedirectUris', index, 'postLogoutRedirectUri']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-input style="width:360px;" v-model:value.trim="item.postLogoutRedirectUri" />
                                </a-form-item>
                                <a-button @click="() => { props.formdata.postLogoutRedirectUris!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
            </a-row>

            <a-row :gutter="16">
                <a-col :span="12">
                    <a-divider orientation="left">身份提供程序限制</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="() => {
                                props.formdata.identityProviderRestrictions?.push({})
                            }">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                            <span style="margin-left: 20px;"></span>
                            <a-checkbox v-model:checked="props.formdata.enableLocalLogin">
                                启动本地登录
                            </a-checkbox>
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.identityProviderRestrictions">
                            <a-input-group compact>
                                <a-form-item :name="['identityProviderRestrictions', index, 'provider']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-select style="width: 360px;" v-model:value="item.provider" show-search allow-clear
                                        :options="PersistedGrantTypes">
                                    </a-select>
                                </a-form-item>
                                <a-button @click="() => { props.formdata.identityProviderRestrictions!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
                <a-col :span="12">
                    <a-divider orientation="left">允许跨域访问的客户端 URL</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="() => {
                                props.formdata.allowedCorsOrigins?.push({})
                            }">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.allowedCorsOrigins">
                            <a-input-group compact>
                                <a-form-item :name="['allowedCorsOrigins', index, 'origin']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-input style="width:360px;" v-model:value.trim="item.origin" />
                                </a-form-item>
                                <a-button @click="() => { props.formdata.allowedCorsOrigins!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
            </a-row>

            <a-divider orientation="left">同意画面</a-divider>
            <a-card>
                <a-row :gutter="16">
                    <a-col :span="8">
                        <a-form-item name="clientUri">
                            <template #label>
                                <div class="label">
                                    <span>显示 URL</span>
                                    <span>在同意画面出现的应用程序 URL</span>
                                </div>
                            </template>
                            <a-input v-model:value.trim="props.formdata.clientUri" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item name="logoUri">
                            <template #label>
                                <div class="label">
                                    <span>Logo URL</span>
                                    <span>在同意画面出现的应用程序 Logo</span>
                                </div>
                            </template>
                            <a-input v-model:value.trim="props.formdata.logoUri" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item name="consentLifetime">
                            <template #label>
                                <div class="label">
                                    <span>生存时间</span>
                                    <span>同意画面Token的生存时间(秒)</span>
                                </div>
                            </template>
                            <a-input-number v-model:value.trim="props.formdata.consentLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="24">
                        <a-form-item>
                            <a-checkbox v-model:checked="props.formdata.requireConsent">
                                <div class="label">
                                    <span>需要同意</span>
                                    <span>指定是否需要同意画面 </span>
                                </div>
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.allowRememberConsent">
                                <div class="label">
                                    <span>记住同意</span>
                                    <span>指定是否在同意画面记录后记住</span>
                                </div>
                            </a-checkbox>
                        </a-form-item>
                    </a-col>

                </a-row>
            </a-card>

            <a-divider orientation="left">令牌</a-divider>
            <a-card>
                <a-row :gutter="16">
                    <a-col :span="8">
                        <a-form-item label="IdentityToken 生存期 (秒)" name="identityTokenLifetime">
                            <a-input-number v-model:value.trim="props.formdata.identityTokenLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="AccessToken 生存期 (秒)" name="accessTokenLifetime">
                            <a-input-number v-model:value.trim="props.formdata.accessTokenLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="AuthorizationCode 生存期 (秒)" name="authorizationCodeLifetime">
                            <a-input-number v-model:value.trim="props.formdata.authorizationCodeLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="允许的 IdentityToken 签名算法" name="allowedIdentityTokenSigningAlgorithms">
                            <a-input v-model:value.trim="props.formdata.allowedIdentityTokenSigningAlgorithms" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="DeviceCode 生存期 (秒)" name="deviceCodeLifetime">
                            <a-input-number v-model:value.trim="props.formdata.deviceCodeLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="UserCode 类型" name="userCodeType">
                            <a-select v-model:value="props.formdata.userCodeType" show-search allow-clear
                                :options="UserCodeTypes">
                            </a-select>
                        </a-form-item>
                    </a-col>

                    <a-col :span="8">
                        <a-form-item label="成对主体盐" name="pairWiseSubjectSalt">
                            <a-input v-model:value.trim="props.formdata.pairWiseSubjectSalt" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="RefreshToken 用法" name="refreshTokenUsage">
                            <a-radio-group v-model:value="props.formdata.refreshTokenUsage" :options="RefreshTokenUsage" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item name="userSsoLifetime">
                            <template #label>
                                <div class="label">
                                    <span>SSO生存期(秒)</span>
                                    <span>身份验证质询之间的时间量</span>
                                </div>
                            </template>
                            <a-input-number v-model:value.trim="props.formdata.userSsoLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="AccessToken 类型" name="accessTokenType">
                            <a-radio-group v-model:value="props.formdata.accessTokenType" :options="AccessTokenType" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8">
                        <a-form-item label="RefreshToken 过期类型" name="refreshTokenExpiration">
                            <a-radio-group v-model:value="props.formdata.refreshTokenExpiration"
                                :options="RefreshTokenExpiration" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8" v-if="props.formdata.refreshTokenExpiration == 0">
                        <a-form-item label="AbsoluteRefreshToken 令牌生存期 (秒)" name="absoluteRefreshTokenLifetime">
                            <a-input-number v-model:value.trim="props.formdata.absoluteRefreshTokenLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="8" v-if="props.formdata.refreshTokenExpiration == 1">
                        <a-form-item label="SlidingRefreshToken 令牌生存期 (秒)" name="slidingRefreshTokenLifetime">
                            <a-input-number v-model:value.trim="props.formdata.slidingRefreshTokenLifetime" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="24">
                        <a-form-item>
                            <a-checkbox v-model:checked="props.formdata.includeJwtId">
                                包含JwtId
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.allowAccessTokensViaBrowser">
                                允许通过浏览器访问令牌
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.updateAccessTokenClaimsOnRefresh">
                                刷新时更新访问令牌声明
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.requirePkce">
                                需要PKCE
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.allowPlainTextPkce">
                                允许纯文字PKCE
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.alwaysIncludeUserClaimsInIdToken">
                                始终在Id令牌中包含用户声明
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.allowOfflineAccess">
                                允许离线访问
                            </a-checkbox>
                            <br />

                        </a-form-item>
                    </a-col>
                </a-row>
            </a-card>

            <a-divider orientation="left">注销会话通道</a-divider>
            <a-card>
                <a-row :gutter="16">
                    <a-col :span="12">
                        <a-form-item label="注销前会话通道 URL" name="frontChannelLogoutUri">
                            <a-input v-model:value.trim="props.formdata.frontChannelLogoutUri" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="12">
                        <a-form-item label="注销后会话通道 URL" name="backChannelLogoutUri">
                            <a-input v-model:value.trim="props.formdata.backChannelLogoutUri" />
                        </a-form-item>
                    </a-col>
                    <a-col :span="24">
                        <a-form-item>
                            <a-checkbox v-model:checked="props.formdata.frontChannelLogoutSessionRequired">
                                需要注销前会话通道
                            </a-checkbox>
                            <br />
                            <a-checkbox v-model:checked="props.formdata.backChannelLogoutSessionRequired">
                                需要注销后会话通道
                            </a-checkbox>
                        </a-form-item>
                    </a-col>
                </a-row>
            </a-card>

            <a-row :gutter="16">
                <a-col :span="12">
                    <a-divider orientation="left">客户端声明</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="props.formdata.claims?.push({})">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                            <span style="margin-left:20px;"></span>
                            <a-checkbox v-model:checked="props.formdata.alwaysSendClientClaims">
                                <div class="label">
                                    <span>总是传送声明</span>
                                    <span>允许客户端声明传送至所有授权类型</span>
                                </div>
                            </a-checkbox>
                        </a-form-item>
                        <a-form-item label="客户端声明前缀" name="clientClaimsPrefix">
                            <a-input v-model:value.trim="props.formdata.clientClaimsPrefix" />
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.claims">
                            <a-input-group compact>
                                <a-form-item :name="['claims', index, 'type']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">

                                    <a-input v-model:value.trim="item.type" placeholder="type" />
                                </a-form-item>
                                <a-form-item :name="['claims', index, 'value']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">

                                    <a-input v-model:value.trim="item.value" placeholder="value" />
                                </a-form-item>
                                <a-button @click="() => { props.formdata.claims!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
                <a-col :span="12">
                    <a-divider orientation="left">属性</a-divider>
                    <a-card>
                        <a-form-item>
                            <a-button @click="() => {
                                props.formdata.properties?.push({})
                            }">
                                <template #icon>
                                    <plus-outlined />
                                </template>
                            </a-button>
                        </a-form-item>
                        <template v-for="(item, index) in props.formdata.properties">
                            <a-input-group compact>
                                <a-form-item :name="['properties', index, 'key']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-input v-model:value.trim="item.key" placeholder="key" />
                                </a-form-item>
                                <a-form-item :name="['properties', index, 'value']" :rules="{
                                    required: true,
                                    message: '不能为空',
                                }">
                                    <a-input v-model:value.trim="item.value" placeholder="value" />
                                </a-form-item>
                                <a-button @click="() => { props.formdata.properties!.splice(index, 1) }">
                                    <template #icon>
                                        <close-outlined />
                                    </template>
                                </a-button>
                            </a-input-group>
                        </template>
                    </a-card>
                </a-col>
            </a-row>
        </a-form>
        <template #extra>
            <a-space>
                <a-button @click="onClose">取消</a-button>
                <a-button type="primary" @click="onSubmit" :loading="loading">提交</a-button>
            </a-space>
        </template>
    </a-drawer>
</template>
<script setup lang="ts">
import { useRequest } from "@/lib/net";
import { message } from 'ant-design-vue';
import type { Rule } from 'ant-design-vue/es/form';
import type { FormInstance } from 'ant-design-vue/lib/form/Form';
import client, { type ClientItem } from "@/api/client";
import {
    GrantTypes, ProtocolTypes,
    SecretTypes, PersistedGrantTypes,
    AccessTokenType, RefreshTokenUsage,
    RefreshTokenExpiration, UserCodeTypes
} from "@/lib/constant/ids4"
import { CloseOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { useApiScopeStore } from "@/store/apiScope";

const props = withDefaults(defineProps<{
    modelValue: boolean
    formdata: ClientItem
}>(), {})

const emit = defineEmits<{
    (event: 'update:modelValue', arg1: boolean): void
    (event: 'success'): void
}>()

var apiScopeStore = useApiScopeStore()
onMounted(async () => {
    await apiScopeStore.all()
})


let title = ref("添加客户端")
watch(() => props.formdata.id, (a) => {
    if (a == undefined || a == 0) {
        title.value = "添加客户端"
    } else {
        title.value = "编辑客户端"
    }
})

const rules: Record<string, Rule[]> = {
    clientId: [{ required: true, message: '不能为空' }],
    clientName: [{ required: true, message: '不能为空' }]
}

const formRef = ref<FormInstance>();
const onClose = () => {
    emit('update:modelValue', false)
}
const onSubmit = async () => {
    try {
        await formRef.value?.validateFields()
    } catch (error) {
        return
    }
    await run(props.formdata)
}

const { run, loading } = useRequest(client.save, {
    manual: true,
    onSuccess: (data) => {
        if (data.code != 0) {
            message.error(data.message)
            return
        }
        formRef.value?.resetFields()
        message.success(data.message)
        emit('update:modelValue', false)
        emit('success')
    }
});

</script>

../../../../api/client../../../../store/apiScope